#ifndef PICCOLO_DESCRIPTOR_SET_H
#define PICCOLO_DESCRIPTOR_SET_H

#include "PiccoloVKCommon.h"

namespace Piccolo
{
    class PiccoloVKDevice;

    class PiccoloVKDescriptorSetLayout
    {
    public:
        PiccoloVKDescriptorSetLayout(PiccoloVKDevice* device, const std::vector<VkDescriptorSetLayoutBinding>& bindings);
        ~PiccoloVKDescriptorSetLayout();

        VkDescriptorSetLayout GetDescriptorSetLayout() const { return mDescriptorSetLayout; }

    private:
        VkDescriptorSetLayout mDescriptorSetLayout = VK_NULL_HANDLE;

        PiccoloVKDevice* mDevice;
    };

    class PiccoloVKDescriptorPool
    {
    public:
        PiccoloVKDescriptorPool(PiccoloVKDevice* device, uint32_t maxSets, const std::vector<VkDescriptorPoolSize>& poolSizes);
        ~PiccoloVKDescriptorPool();

        std::vector<VkDescriptorSet> AllocateDescriptorSet(PiccoloVKDescriptorSetLayout* descriptorSetLayout, uint32_t count);

    private:
        VkDescriptorPool mDescriptorPool = VK_NULL_HANDLE;

        PiccoloVKDevice* mDevice;
    };

    class DescriptorSetWriter
    {
    public:
        static VkDescriptorBufferInfo BuildBufferInfo(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range);

        static VkDescriptorImageInfo BuildImageInfo(VkSampler sampler, VkImageView imageView);

        static VkWriteDescriptorSet WriteBuffer(VkDescriptorSet dstSet, uint32_t dstBinding, VkDescriptorType descriptorType, VkDescriptorBufferInfo* pBufferInfo);

        static VkWriteDescriptorSet WriteImage(VkDescriptorSet dstSet, uint32_t dstBinding, VkDescriptorType descriptorType, VkDescriptorImageInfo* pImageInfo);

        static void UpdateDescriptorSets(VkDevice device, const std::vector<VkWriteDescriptorSet>& writes);
    };
}

#endif